/*!
 *2018.07.04 wxd
 */
;
(function(factory) {
	if(typeof define === 'function' && define.amd) {
		define(['jquery', 'leaflet', 'wicket.leaflet', "d3", "d3pie", "mustache", 'leaflet.ChineseTmsProviders', 'leaflet.WMTS',
			'leaflet.measure', 'leaflet.MousePosition', 'leaflet.groupedlayercontrol', 'leaflet.Zoominfo', 'leaflet.markercluster',
			"leaflet.custom", 'css!../lib/vw/css/vw.map.css'
		], factory);
	} else {
		if(typeof module === 'object' && module.exports) {
			//
		} else {
			factory(window.jQuery);
		}
	}
})(function($, L, Wkt, d3, d3pie, mustache) {
	'use strict';
	var pluginName = "vw_map";

	var defaults = {
		showMeasureControl: false,
		showZoominfo: true,
		showMousePosition: true,
		$container: null,
		height: 45,
		heightDiff: 45,
		defaultMapview: {
			lat: 36,
			lon: 105,
			zoom: 4
		},
		minZoom: 1,
		maxZoom: 22,
		maxBounds: {
			xMin: -180,
			yMIn: -90,
			xMax: 180,
			yMax: 90,
		},
		defaultLayer: "image", //normal
		geoJsonURL: "",
		WMTSLayerURL: "",
		tileURL: "",
		disableClusteringAtZoom: 19,
		pointSize: 10,
		labelColors: '#e65414',
		svgColors: ["#44b9b0", "#e65414", "#7c37c0", "#d1c87f", "#cc9fb1", "#248838", "#ffff4c", "#ffeb4c", "#ffd84c", "#ffc44c"],
		pointbgColor: "#EE7600",
		textColor: "#FFFFFF",
		clusterColor: "#FF6347",
		gradientsColors: ["#ffff4c", "#ffeb4c", "#ffd84c", "#ffc44c", "#ffb04c", "#ff9d4c", "#ff894c", "#ff754c", "#ff624c"],
		fillColors: ["#ff0000", "#ffff00", "#00ff00", "#0000ff", "#ffeb4c", "#ffd84c", "#ffc44c"],
		icons: [],
		onInitialized: null,
		onMouseoverMarker: null,
		onMouseoutMarker: null,
		onClickMarker: null,
		OnZoom: null
	};

	var methods = [
		'drawLabel',
		'drawLabelCount',
		'drawPoint',
		'drawCluster',
		'drawPolygon',
		'drawIconMap',
		'drawSVGMap',
		'getMap',
		'getLayer',
		'getLayerByID',
		'getMarkers',
		'refresh',
		'resetMapview',
		'highlightMap',
		'cancelHighlightMap',
		'destroy'
	];

	var MAP_TOOL_TIP = '<p class="mapTooltip_title">{{title}}</p>' +
		'<ul class="mapTooltip_info">' +
		'	<li class="mapTooltip_divider"></li>' +
		'	{{#cols}}<li class="mapTooltip_prop">' +
		'		<span>{{title}}：</span>' +
		'		<span>{{info}}</span>' +
		'	</li>{{/cols}}' +
		'</ul>' +
		'<p class="mapTooltip_tag"></p>';

	var LEGEND = '<div class="legend_subject">' +
		'	{{#legends}}<div class="legend_line" style="height:{{lineHeight}};line-height:{{lineHeight}}">' +
		'		<div style="background:{{color}};border-radius:{{radius}};width:{{width}};height:{{height}};margin-top:{{marginTop}};margin-left:{{marginLeft}};"></div>' +
		'		<span>{{label}}</span>' +
		'	</div>{{/legends}}' +
		'</div>';

	var vw_map = function(element, options) {
		this.$element = $(element);
		this.options = $.extend({}, defaults, options);
		this._defaults = defaults;
		this._name = pluginName + this.$element.attr('id');
		this.version = 'v1.0.0';

		this._init();
	}

	vw_map.prototype = {
		_init: function() {
			var that = this;
			that.$element.empty();

			var _tdt_normal_m = L.tileLayer.chinaProvider('TianDiTu.Normal.Map', {
				maxZoom: 22,
				minZoom: 3
			});

			var _tdt_normal_a = L.tileLayer.chinaProvider('TianDiTu.Normal.Annotion', {
				maxZoom: 22,
				minZoom: 3
			});

			var _tdt_img_m = L.tileLayer.chinaProvider('TianDiTu.Satellite.Map', {
				maxZoom: 22,
				minZoom: 3
			});

			var _tdt_img_a = L.tileLayer.chinaProvider('TianDiTu.Satellite.Annotion', {
				maxZoom: 22,
				minZoom: 3
			});

			var baseLayers = {
				"天地图矢量地图": L.layerGroup([_tdt_normal_m, _tdt_normal_a]),
				"天地图影像地图": L.layerGroup([_tdt_img_m, _tdt_img_a]),
			};

			var defaultLayer;
			if(that.options.defaultLayer == "image") {
				defaultLayer = baseLayers["天地图影像地图"];
			} else {
				defaultLayer = baseLayers["天地图矢量地图"];
			}

			that._map = L.map(that.$element[0].id, {
				zoomControl: false,
				attributionControl: false,
				minZoom: that.options.minZoom,
				maxZoom: that.options.maxZoom,
				maxBounds: L.latLngBounds(L.latLng(that.options.maxBounds.yMin, that.options.maxBounds.xMin), L.latLng(that.options.maxBounds.yMax, that.options.maxBounds.xMax)),
				layers: defaultLayer
			});

			that._map.setView([that.options.defaultMapview.lat, that.options.defaultMapview.lon], that.options.defaultMapview.zoom);

			that._layerControl = L.control.groupedLayers(baseLayers, {}, {
				groupCheckboxes: true
			});
			that._map.addControl(that._layerControl);

			if(that.options.WMTSLayerURL && that.options.tileURL) {
				AddCustomWMTSLayers();
			}

			if(that.options.showZoominfo) {
				new L.Control.Zoominfo({
					position: 'topleft', //bottomright
				}).addTo(that._map);
			}

			if(that.options.showMousePosition) {
				L.control.mousePosition({
					position: 'bottomleft',
				}).addTo(that._map);
			}

			if(that.options.showMeasureControl) {
				new L.Control.Measure({
					localization: 'cn',
					primaryLengthUnit: 'meters',
					secondaryLengthUnit: 'kilometers',
					primaryAreaUnit: 'sqmeters',
					secondaryAreaUnit: 'hectares',
					position: 'topright',
				}).addTo(that._map);
			}

			that._layers = [];
			that._markers = [];
			that._wkt = new Wkt.Wkt();
			that._leafletLegend = "leafletCustomLegend";

			L.Marker.SVGMarker = L.Marker.extend({
				options: {
					"id": 0,
					"type": "",
					"code": 0,
					"data": {},
					"size": 10
				},
				initialize: function(latlng, options) {
					options = L.Util.setOptions(this, options);
					this._latlng = latlng;
				},
				onAdd: function(map) {
					L.Marker.prototype.onAdd.call(this, map);
					if(this.options.type == "pie") {
						D3Pie('marker_svg_' + this.options.id, this.options.data, this.options.size);
					} else if(this.options.type == "bar") {
						SVGBar('marker_svg_' + this.options.id, this.options.data, this.options.size);
					} else {
						return;
					}
				}
			});

			that.$element.css('margin-top', '10px');

			that.resetMapview();
			$(window).resize(that.resetMapview);

			that.$element.trigger("onInitialized");
			if(that.options.onInitialized) {
				that.options.onInitialized.call(that);
			}

			if(that.options.OnZoom) {
				that._map.on('zoomend', that.options.OnZoom);
			}
		},

		resetMapview: function() {
			var that = this;
			if(that.$element) {
				var containerHeight;
				if(that.options.$container) {
					containerHeight = that.options.$container.height();
				} else {
					if(that.options.height) {
						containerHeight = that.options.height;
					} else {
						containerHeight = $(window).height();
					}
				}

				that.height = containerHeight - that.options.heightDiff;

				that.$element.height(that.height);
				L.Util.requestAnimFrame(that._map.invalidateSize, that._map, false, that._map._container);
			}
		},

		refresh: function() {
			var that = this;
			if(that._layers) {
				for(var i = that._layers.length - 1; i >= 0; i--) {
					if(that._layers[i].name.split('_')[0] == "Custom") {
						that._map.removeLayer(that._layers[i].layer);
						that._layers.splice(i, 1);
						$('#' + that._leafletLegend).remove();
					}
				}
			}
		},

		getMap: function() {
			return this._map;
		},

		getLayer: function(name) {
			var that = this;
			if(that._layers) {
				for(var i = 0; i < that._layers.length; i++) {
					if(that._layers[i].name == name) {
						return that._layers[i].layer;
					}
				}
			}
			return null;
		},

		getLayerByID: function(id) {
			if(this._layers) {
				return this._layers[id].layer;
			}
			return null;
		},

		getMarkers: function() {
			return this._markers;
		},

		_bindEvent: function(marker) {
			var that = this;
			marker.on('mouseover', function(e) {
				if(that.options.onMouseoverMarker) {
					that.options.onMouseoverMarker.call(that, e.target.options.code);
				}
			}).on('mouseout', function(e) {
				if(that.options.onMouseoutMarker) {
					that.options.onMouseoutMarker.call(that, e.target.options.code);
				}
			}).on('click', function(e) {
				if(that.options.onClickMarker) {
					that.options.onClickMarker.call(that, e.target.options.code);
				}
			});
		},

		_loadLayerData: function(layerName) {
			var serverVersion = 0;
			var cacheFlag = "vw_map_layer_";
			var localCache = JSON.parse(localStorage.getItem(cacheFlag + layerName));
			if(localCache && localCache.version == serverVersion) {
				that.layers[localCache.layerName] = localCache.data;
			} else {
				if(!that.options.geoJsonURL) {
					return;
				}

				vw_common.customAjax({
					url: that.options.geoJsonURL,
					type: "GET",
					dataType: "json",
					async: false,
					data: {
						layer: layerName
					},
				}, function(e) {
					that.layers[layerName] = e.data;
					localStorage.setItem(cacheFlag + layerName, JSON.stringify({
						name: layerName,
						data: e.data,
						version: e.version
					}));

				});
			}
		},

		drawLabel: function(data, zoomto) {
			if(!data) {
				return;
			}
			var that = this;
			var _layerGroup = new L.layerGroup();

			that._columns = data.head.columns;
			that._idIndex = data.head.id;
			that._nameIndex = data.head.name;
			that._themesIndexs = data.head.themes;
			that._enums = data.head.enums;

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, that._popupText(val.content));

				var marker = new L.Marker(L.latLng(val.latlon), {
					code: val.content[that._idIndex], //用于Highlight时找对应
					icon: new L.DivIcon({
						html: '<div style="background:' + that.options.svgColors[that._enums.dic[val.content[that._enums.key]].id] + ';color:' + that.options.textColor + ';"><span>' + val.content[that._nameIndex] + '</span></div> ',
						className: "marker-addPoints point-icon",
						iconSize: new L.Point(30, 15),
					})
				}).bindTooltip(pop).addTo(_layerGroup);

				that._bindEvent(marker);

				that._markers.push(marker);
			});

			if(points.length > 0) {
				that._map.addLayer(_layerGroup);
				if(zoomto) {
					that._map.fitBounds(L.latLngBounds(points));
				}

				that._layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});

				var legend = [];
				$.each(that._enums.dic, function(k, val) {
					legend.push({
						color: that.options.svgColors[val.id],
						label: val.text
					});
				});

				that._renderLegend(legend);
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		drawLabelCount: function(data, zoomto, label) {
			if(!data) {
				return;
			}
			var that = this;
			var _layerGroup = new L.layerGroup();

			that._columns = data.head.columns;
			that._idIndex = data.head.id;
			that._nameIndex = data.head.name;
			that._themesIndexs = data.head.themes;
			that._enums = data.head.enums;

			var items = {};
			data.body.forEach(function(item) {
				if(!items[item.content[that._themesIndexs[0]]]) {
					items[item.content[that._themesIndexs[0]]] = {};
				}
				items[item.content[that._themesIndexs[0]]]['count'] = (items[item.content[that._themesIndexs[0]]]['count'] || 0) + 1;
				items[item.content[that._themesIndexs[0]]]['content'] = item.content;
				items[item.content[that._themesIndexs[0]]]['latlon'] = item.latlon;
			});

			var points = [];
			var flag = 0;
			$.each(items, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, that._popupText(val.content));

				var marker = new L.Marker(L.latLng(val.latlon), {
					code: k, //用于Highlight时找对应
					icon: new L.DivIcon({
						html: '<div style="background:' + that.options.labelColors + ';color:' + that.options.textColor + ';"><span>' + val.count + '</span></div> ',
						className: "marker-addPoints point-icon",
						iconSize: new L.Point(25, 15),
					})
				}).bindTooltip(pop).addTo(_layerGroup);

				that._bindEvent(marker);

				that._markers.push(marker);
			});

			if(points.length > 0) {
				that._map.addLayer(_layerGroup);
				if(zoomto) {
					that._map.fitBounds(L.latLngBounds(points));
				}

				that._layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});

				var legend = {
					color: that.options.labelColors,
					label: label
				};
				that._renderLegend(legend);
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		drawPoint: function(data, zoomto, withLine, size) {
			if(!data) {
				return;
			}
			if(!size) {
				size = 10;
			}
			var that = this;
			var _layerGroup = new L.layerGroup();

			that._columns = data.head.columns;
			that._idIndex = data.head.id;
			that._nameIndex = data.head.name;
			that._themesIndexs = data.head.themes;
			that._enums = data.head.enums;

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				//				if(val.latlon[0] == 0 || val.latlon[1] == 0) {
				//					return true;
				//				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, that._popupText(val.content));

				var marker = new L.Marker(L.latLng(val.latlon), {
					code: val.content[that._idIndex], //用于Highlight时找对应
					icon: new L.DivIcon({
						html: '<div style="background:' + that.options.svgColors[that._enums.dic[val.content[that._enums.key]].id] + ';width:100%;height:100%"></div> ',
						className: "marker-addPoints point-icon",
						iconSize: new L.Point(size, size),
					})
				}).bindTooltip(pop).addTo(_layerGroup);

				that._bindEvent(marker);

				that._markers.push(marker);
			});

			if(points.length > 0) {
				if(withLine) {
					L.polyline(points, {
						color: 'red',
						dashArray: '5,5'
					}).addTo(_layerGroup);
				};
				that._map.addLayer(_layerGroup);
				if(zoomto) {
					that._map.fitBounds(L.latLngBounds(points));
				}

				that._layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});

				var legend = [];
				$.each(that._enums.dic, function(k, val) {
					legend.push({
						color: that.options.svgColors[val.id],
						label: val.text
					});
				});

				that._renderLegend(legend);
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		drawCluster: function(data, zoomto, size, zoomlevel, label) {
			if(!data) {
				return;
			}
			if(!size) {
				size = 20;
			}
			var that = this;
			that._columns = data.head.columns;
			that._idIndex = data.head.id;
			that._nameIndex = data.head.name;
			that._themesIndexs = data.head.themes;
			that._enums = data.head.enums;

			var _layerGroup = new L.MarkerClusterGroup({
				spiderfyOnMaxZoom: true,
				showCoverageOnHover: false,
				singleMarkerMode: true,
				disableClusteringAtZoom: that.options.disableClusteringAtZoom,
				iconCreateFunction: function(e) {
					var count = e.getChildCount();
					var classtype = "marker-cluster";
					var iconSize = {
						width: size * 2,
						height: size * 2
					};
					if(count < 2) {
						count = "";
						classtype = "marker-custom";
						iconSize = {
							width: size,
							height: size
						}
					}
					return new L.divIcon({
						html: '<div style="background:' + that.options.clusterColor + ';"><span>' + count + '</span></div>',
						className: classtype,
						iconSize: new L.Point(iconSize.width, iconSize.height)
					})
				}
			});

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, that._popupText(val.content));

				var marker = new L.Marker(L.latLng(val.latlon), {
					code: val.content[that._idIndex] //用于Highlight时找对应
				}).bindTooltip(pop).addTo(_layerGroup);

				that._bindEvent(marker);

				that._markers.push(marker);
			});

			if(points.length > 0) {
				that._map.addLayer(_layerGroup);
				if(zoomto) {
					that._map.fitBounds(_layerGroup.getBounds());
					if(zoomlevel) {
						that._map.setZoom(zoomlevel);
					}
				};

				that._layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});

				var legend = {
					color: that.options.clusterColor,
					label: label
				};
				that._renderLegend(legend);
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		drawPolygon: function(data, zoomto, style) {
			if(!data) {
				return;
			}
			var that = this;
			if(!style) {
				style = {
					color: "#3388ff",
					weight: 2
				};
			}

			var _layerGroup = new L.MarkerClusterGroup();

			that._columns = data.head.columns;
			that._idIndex = data.head.id;
			that._nameIndex = data.head.name;
			that._themesIndexs = data.head.themes;
			that._enums = data.head.enums;

			$.each(data.body, function(k, val) {
				var pop = mustache.render(MAP_TOOL_TIP, that._popupText(val.content));

				that._wkt.read(val.wkt);
				var marker = that._wkt.toObject();
				var markerstyle = {
					code: val.content[that._idIndex], //用于Highlight时找对应
					weight: style.weight
				};
				if(that._enums && that._enums.key && Object.getOwnPropertyNames(that._enums.dic).length) {
					markerstyle.fillColor = that.options.fillColors[that._enums.dic[val.content[that._enums.key]].id];
					markerstyle.color = that.options.fillColors[that._enums.dic[val.content[that._enums.key]].id];
				} else {
//					markerstyle.fill = false;
					markerstyle.color = style.color;
				}
				marker.setStyle(markerstyle).bindTooltip(pop).addTo(_layerGroup);

				that._bindEvent(marker);

				that._markers.push(marker);
			});

			that._map.addLayer(_layerGroup);
			if(zoomto) {
				that._map.fitBounds(_layerGroup.getBounds());
			}

			that._layers.push({
				name: "Custom_" + _layerGroup._leaflet_id,
				layer: _layerGroup
			});

			if(that._enums && that._enums.key && that._enums.dic) {
				var legend = [];
				$.each(that._enums.dic, function(k, val) {
					legend.push({
						color: that.options.fillColors[val.id],
						label: val.text
					});
				});

				that._renderLegend(legend);
			}
		},

		drawIconMap: function(data, zoomto, size) {
			if(!data) {
				return;
			}
			if(!size) {
				size = 10;
			}
			var that = this;
			var _layerGroup = new L.layerGroup();

			that._columns = data.head.columns;
			that._idIndex = data.head.id;
			that._nameIndex = data.head.name;
			that._themesIndexs = data.head.themes;
			that._enums = data.head.enums;

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, that._popupText(val.content));

				var marker = L.marker(L.latLng(val.latlon), {
					code: val.content[that._idIndex], //用于Highlight时找对应
					type: val.content[that._enums.key],
					icon: L.icon({
						iconUrl: that.options.icons[that._enums.dic[val.content[that._enums.key]].id],
						className: 'obj-icon',
						iconSize: [size, size],
					})
				}).bindTooltip(pop).addTo(_layerGroup);

				that._bindEvent(marker);

				that._markers.push(marker);
			});

			if(points.length > 0) {
				that._map.addLayer(_layerGroup);

				if(zoomto) {
					that._map.fitBounds(L.latLngBounds(points));
				};

				that._layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		drawSVGMap: function(data, zoomto, type, size) {
			if(!data) {
				return;
			}
			var that = this;
			var _layerGroup = new L.layerGroup();

			that._columns = data.head.columns;
			that._idIndex = data.head.id;
			that._nameIndex = data.head.name;
			that._markerThemesIndexs = data.head.markerThemes;
			that._themesIndexs = data.head.themes;
			that._enums = data.head.enums;

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, that._popupText(val.content));

				var svgdata = [];
				for(var i in that._markerThemesIndexs) {
					svgdata.push({
						"id": val.content[that._idIndex],
						"value": parseFloat(val.content[that._markerThemesIndexs[i]]),
						"label": that._columns[that._markerThemesIndexs[i]].title,
						"color": that.options.svgColors[i]
					})
				};
				var marker = new L.Marker.SVGMarker(L.latLng(val.latlon), {
					id: k, //d3pie需要
					type: type,
					code: val.content[that._idIndex], //用于Highlight时找对应
					data: svgdata,
					size: size,
					icon: L.divIcon({
						className: 'svg-icon',
						html: '<div id="marker_svg_' + k + '" ></div>' //svg需要
					})
				}).bindTooltip(pop).addTo(_layerGroup);

				that._bindEvent(marker);

				that._markers.push(marker);
			});

			if(points.length > 0) {
				that._map.addLayer(_layerGroup);
				if(zoomto) {
					that._map.fitBounds(L.latLngBounds(points));
				}
				that._layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});

				var legend = [];
				for(var i in that._markerThemesIndexs) {
					legend.push({
						"label": that._columns[that._markerThemesIndexs[i]].title,
						"color": that.options.svgColors[i],
					})
				}
				that._renderLegend(legend);
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		_popupText: function(data) {
			var that = this;
			var properties = [];
			if(that._themesIndexs) {
				$.each(that._themesIndexs, function(k, val) {
					var item = {
						title: that._columns[val].title,
						info: data[val]
					};
					properties.push(item);
				});
			}
			var retval = {
				title: data[that._nameIndex],
				cols: properties
			};
			return retval;
		},

		_renderLegend: function(data) {
			var that = this;
			$('#' + that._leafletLegend).remove();
			L.control.custom({
				id: that._leafletLegend,
				position: 'bottomright',
				content: mustache.render(LEGEND, {
					legends: data
				}),
			}).addTo(that._map);
		},

		highlightMap: function(index) {
			var that = this;
			that.cancelHighlightMap();

			if(that._layers) {
				for(var i = 0; i < that._layers.length; i++) {
					var ls = that._layers[i].layer.getLayers();
					for(var j = 0; j < ls.length; j++) {
						if(ls[j].options.code.trim() == index.trim()) {
							ls[j].openTooltip();
							that._curMarker = ls[j];
							return;
						}
					}
				}
			}
		},

		cancelHighlightMap: function() {
			if(this._curMarker) {
				this._curMarker.closeTooltip();
			}
		},

		destroy: function() {
			this.$element.empty();
		}
	}

	function AddWMTS(url, name) {
		return new L.TileLayer.WMTS(url, {
			layer: name,
			style: "normal",
			tilematrixSet: "PM",
			format: "image/jpeg",
		});
	}

	function AddCustomWMTSLayers() {
		var that = this;
		$.ajax({
			url: that.options.WMTSLayerURL,
			type: 'GET',
			async: false,
			dataType: 'json',
			success: function(e) {
				for(var i = 0; i < e.layers.length; i++) {
					var group = e.layers[i];
					if(group.layers) {
						for(var j = 0; j < group.layers.length; j++) {
							var layer = group.layers[i];
							if(layer.tilePath != "") {
								var wmts = new L.TileLayer.WMTS(that.options.ReadTile + layer.tilePath, {
									TILEMATRIXSET: "default028mms",
								});
								that._layerControl.addOverlay(wmts, layer.name, group.name);
								that._layers.push({
									name: "WMTS_" + layer.name,
									layer: wmts
								});
							}
						}
					} else {
						if(group.tilePath != "") {
							var wmts = new L.TileLayer.WMTS(that.options.ReadTile + group.tilePath, {
								TILEMATRIXSET: "default028mms",
							});
							that._layerControl.addOverlay(wmts, group.name, "");
							that._layers.push({
								name: "WMTS_" + group.name,
								layer: wmts
							});
						}
					}
				}
			}
		})
	}

	function D3Pie(div, data, size) {
		var option = {
			size: {
				canvasHeight: size * 2,
				canvasWidth: size * 2,
				pieInnerRadius: 0,
				pieOuterRadius: size - 3
			},
			labels: {
				outer: {
					format: "none"
				},
				inner: {
					format: "none"
				}
			},
			data: {
				sortOrder: "value-asc",
				content: data
			},
			effects: {
				load: {
					effect: "none"
				},
				pullOutSegmentOnClick: {
					effect: "none"
				}
			},
			tooltips: {
				enabled: false
			},
			opacity: 0.7
		};
		new d3pie(div, option);
	}

	function SVGBar(div, data, size) {
		var canvasHeight = size * 2;
		var canvasWidth = size;
		var dom = document.getElementById(div);
		var svg = d3.select(dom).append("svg").attr("width", canvasWidth).attr("height", canvasHeight);
		var padding = {
			left: 0,
			right: 0,
			top: 1,
			bottom: 1
		};

		var vals = [];
		for(var i in data) {
			vals.push(data[i].value)
		}
		var XRange = d3.scale.ordinal().domain(d3.range(vals.length)).rangeRoundBands([0, canvasWidth - padding.left - padding.right]);
		var maxval = d3.max(vals);
		var minval = d3.min(vals);
		if(minval > 0) {
			if(minval > (maxval - minval) / 2) {
				minval = minval - (maxval - minval) / 2
			} else {
				minval = 0
			}
		} else {
			minval = minval - (maxval - minval) / 2
		}
		var yRange = d3.scale.linear().domain([minval, maxval]).range([canvasHeight - padding.top - padding.bottom, 0]);
		svg.selectAll(".MyRect").data(data).enter().append("rect")
			.attr("class", "MyRect")
			.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
			.attr("x", function(i, e) {
				return XRange(e)
			})
			.attr("width", XRange.rangeBand())
			.attr("y", function(e) {
				return yRange(e.value)
			})
			.attr("height", function(e) {
				return canvasHeight - padding.top - padding.bottom - yRange(e.value)
			})
			.attr("fill", function(i, e) {
				return i.color
			})
			.style("fill-opacity", 0.7);
	}

	$.fn[pluginName] = function(option) {
		var value;
		var args = Array.prototype.slice.call(arguments, 1);
		this.each(function() {
			var $this = $(this);
			var data = $this.data(pluginName);
			if(typeof option === 'string') {
				if($.inArray(option, methods) < 0) {
					throw new Error("该方法不存在: " + option);
				}
				if(!data) {
					return;
				}
				value = data[option].apply(data, args);
				if(option === 'destroy') {
					$this.removeData(pluginName);
				}
			}
			if(!data) {
				$this.data(pluginName, (data = new vw_map(this, option)));
			}
		});
		return typeof value === 'undefined' ? this : value;
	};
});